/*
 * Copyright (C) 2010 TopCoder Inc., All Rights Reserved.
 */
package com.hercules.xre.protocol.testing.netty;

import com.hercules.xre.protocol.testing.Helper;
import com.topcoder.util.log.Log;
import com.topcoder.util.log.LogManager;

import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;

import java.util.List;


/**
 * <p>
 * Channel Listener Future that is responsible for informing CommandSender that commands have
 * been successfully delivered. If delivery wasn't successful then nothing needs to be done.
 * Exception will be logged by separate ChannelFutureListener and referenced CommandSender
 * will be informed about connection problems.
 * </p>
 *
 * <p>
 * <strong>Thread-safety:</strong> This class is immutable and thus it is thread safe.
 * </p>
 *
 * @author TCSDESIGNER, TCSDEVELOPER
 * @version 1.0
 */
public class CommandsDeliveryStatusFutureListener implements ChannelFutureListener {
    /**
     * <p>
     * Logger that is used to log activities and errors. It is initialized to
     * LogManager.getLog(CommandsDeliveryStatusFutureListener.class.getName()). Can not be null, never changes after
     * initialization.
     * </p>
     */
    private static final Log LOGGER = LogManager.getLog(CommandsDeliveryStatusFutureListener.class.getName());

    /**
     * <p>
     * List of commands that are being sent. Can't be null. Can't contain null values, shouldn't be empty. Initialized
     * in constructor, never changes after that.
     * </p>
     */
    private final List<String> commandsBeingSent;

    /**
     * <p>
     * Command sender (in current design a ChannelHandler) that is responsible for sending commands. This object should
     * be informed about successful delivery. Cannot be null. Initialized in constructor, never changes after that.
     * </p>
     */
    private final CommandSender commandSender;

    /**
     * <p>
     * Creates new instance.
     * </p>
     *
     * @param commandSender command sender, can't be null
     * @param commands list of commands that are being sent, can't be null, can't be empty, can't contain empty/null
     *        command.
     * @throws IllegalArgumentException if any parameter is null, or commands is empty or contains null element.
     */
    public CommandsDeliveryStatusFutureListener(CommandSender commandSender, List<String> commands) {
        final String signature = "CommandsDeliveryStatusFutureListener#ctor";
        Helper.logEnter(signature, new String[] {"commandSender", "commands"},
            new Object[] {commandSender, commands}, LOGGER);

        try {
            Helper.checkNull(commandSender, "commandSender", signature, LOGGER);
            Helper.checkList(commands, "commands", signature, LOGGER);
            this.commandSender = commandSender;
            this.commandsBeingSent = commands;
        } finally {
            Helper.logExit(signature, null, LOGGER);
        }
    }

    /**
     * <p>
     * Method called by Netty framework when channel operation has been completed. If operation was successful then
     * Command sender should be notified about this.
     * </p>
     *
     * @param future channel future representing message delivery event, can't be null
     * @throws IllegalArgumentException if future is null
     */
    public void operationComplete(ChannelFuture future) {
        final String signature = "CommandsDeliveryStatusFutureListener#operationComplete";
        Helper.logEnter(signature, new String[] {"future"}, new Object[] {future}, LOGGER);

        try {
            Helper.checkNull(future, "future", signature, LOGGER);

            if (future.isSuccess()) {
                commandSender.commandsDelivered(commandsBeingSent);
            }
        } finally {
            Helper.logExit(signature, null, LOGGER);
        }
    }
}
